let activeUpdate;

class Dep {
    constructor() {
        this.subscribers = new Set();
    }

    depend() {
        if (activeUpdate) {
            this.subscribers.add(activeUpdate);
        }
    }

    notify() {
        this.subscribers.forEach((sub) => sub());
    }
}

export function autorun(update) {
    function wrappedUpdate() {
        activeUpdate = wrappedUpdate;
        update();
        activeUpdate = null;
    }

    wrappedUpdate();
}

export function observe(obj) {
    const dep = new Dep();

    Object.keys(obj).forEach((key) => {
        let internalValue = obj[key];

        Object.defineProperty(obj, key, {
            get() {
                dep.depend();
                return internalValue;
            },
            set(newValue) {
                internalValue = newValue;
                dep.notify();
            },
        });
    });
}
